package token

import (
	"errors"
	"github.com/zhongshaofa/swan-jobs/internal/models"
	"github.com/zhongshaofa/swan-jobs/internal/utils"
	"strconv"
	"sync"
	"time"
)

var once sync.Once

// 用户token管理单例
var userTokenMangerInstance *userTokenManger

type Token struct {
	UserId   int
	RoleType int
	Token    string
	LoginAt  time.Time
	ExpireAt time.Time
	IsAlways bool
}

type userTokenManger struct {
	List []*Token
	mu   sync.Mutex
}

func (l *userTokenManger) Create(u *models.User) *Token {
	userId := int(u.ID)
	l.Clear(userId)

	l.mu.Lock()
	defer l.mu.Unlock()

	tokenString := l.buildToken(userId)

	expireAt := time.Now()
	dd, _ := time.ParseDuration("+24h")
	expireAt.Add(dd)

	token := Token{
		UserId:   userId,
		RoleType: u.RoleType,
		Token:    tokenString,
		LoginAt:  time.Now(),
		ExpireAt: expireAt,
		IsAlways: false,
	}
	l.List = append(l.List, &token)
	return &token
}

func (l *userTokenManger) Verify(tokenString string) (error, Token) {
	var token = new(Token)
	verify := false
	if l != nil {
		for _, t := range l.List {
			if t.Token == tokenString {
				token = t
				verify = true
				break
			}
		}
	}

	if !verify {
		return errors.New("验证token失败"), *token
	}
	if !token.ExpireAt.Before(time.Now()) {
		return errors.New("token已过期，请重新登录"), *token
	}
	return nil, *token
}

func (l *userTokenManger) Clear(userId int) {
	l.mu.Lock()
	defer l.mu.Unlock()

	if l == nil {
		return
	}
	for index, token := range l.List {
		if token.UserId == userId {
			l.List = append(l.List[:index], l.List[index+1:]...)
			break
		}
	}
}

func (l *userTokenManger) Refresh() {

}

func (l *userTokenManger) buildToken(userId int) string {
	return utils.Md5("token" + strconv.Itoa(userId) + time.Now().String())
}

// GetUserTokenMangerInstance 获取用户token管理单例
func GetUserTokenMangerInstance() *userTokenManger {
	once.Do(func() {
		userTokenMangerInstance = &userTokenManger{
			List: nil,
		}
	})
	return userTokenMangerInstance
}
